package com.yuneec.fly.views;

import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.graphics.Color;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;

import com.yuneec.fly.R;

public class CounterView extends TextView {

    public static final int COUNT_UP = 1;
    public static final int COUNT_DOWN = 2;
    private static final String TAG = "CounterView";
    private int mTrigger = 0;
    private int mStyle = COUNT_UP;
    private boolean mRunning = false;
    private long mDuration;    //ms
    private long mBase;
    private OnTickListener mOnTickListener;
    private String mFormatString;
    private Timer mUpdateTimer;
    private UpdateTimerTask mUpdateTimerTask;
    private int mNormalColor;
    private int mTickEndColor = Color.RED;
    //	private Handler mHandler = new Handler();
    private int mAlmostEndThreshold = 60000; //ms
    private boolean mIsAlmostEndPosted = false;
    private int offsetSecond = 0;

    public CounterView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public CounterView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CounterView(Context context) {
        super(context);
        init(context);
    }

    private void init(Context context) {
        mFormatString = context.getString(R.string.counter_format_time);
        mNormalColor = getTextColors().getDefaultColor();
    }

    public boolean isStarted() {
        return mRunning;
    }

    public void start() {
        if (mDuration == 0) {
            Log.i(TAG, "duration is 0, no need to start");
            return;
        }

        if (mRunning) {
            Log.e(TAG, "Counter is already running");
            return;
        }
        mRunning = true;
        if (mDuration <= mAlmostEndThreshold) {
            mIsAlmostEndPosted = true;
        }

        if (mStyle == COUNT_DOWN) {
            mBase = SystemClock.elapsedRealtime() + mDuration;
        } else {
            mBase = SystemClock.elapsedRealtime();
        }
//		mHandler.post(mUpdateRunnable);
        offsetSecond = 0;
        mUpdateTimer = new Timer("Counter");
        mUpdateTimerTask = new UpdateTimerTask();
        mUpdateTimer.scheduleAtFixedRate(mUpdateTimerTask, 0, 1000);
    }

    public void start(int setCurrentTime) {
        start();

        if (setCurrentTime < 0) {
            return;
        }

        if (mStyle == COUNT_DOWN) {
            this.offsetSecond = (int) ((setCurrentTime * 1000 + SystemClock.elapsedRealtime()) - mBase) / 1000;
        } else {
            this.offsetSecond = (int) (setCurrentTime * 1000 + mBase - SystemClock.elapsedRealtime()) / 1000;
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        setText(setFormatTime(0));
    }

    public void stop() {
        mRunning = false;
        mIsAlmostEndPosted = false;
//		removeCallbacks(mUpdateRunnable);
        if (mUpdateTimer != null) {
            mUpdateTimer.cancel();
            if (mUpdateTimerTask != null) {
                mUpdateTimerTask.cancel();
            }
            mUpdateTimer = null;
        }
    }

    public void setStyle(int style) {
        if (mRunning) {
            Log.e(TAG, "Counter already running cannot change style");
            return;
        }
        mStyle = style;

        //refresh textview
        if (mStyle == COUNT_DOWN) {
            setText(setFormatTime(mDuration));
        } else {
            setText(setFormatTime(0));
        }
    }

    public int getTrigger() {
        return mTrigger;
    }

    public void setTrigger(int trigger) {
        mTrigger = trigger;
    }

    public int getStyle() {
        return mStyle;
    }

    public int getDuration() {
        return (int) (mDuration / 1000);
    }

    public void setDuration(int seconds) {
        if (mRunning) {
            Log.e(TAG, "Counter already running cannot change duration");
            return;
        }
        mDuration = seconds * 1000;
        if (mStyle == COUNT_DOWN) {
            setText(setFormatTime(mDuration));
        } else {
            setText(setFormatTime(0));
        }
    }

    public interface OnTickListener {
        void onTick(int seconds);

        void onAlmostEnd();

        void onEnd();
    }

    public void setTickListener(OnTickListener listener) {
        mOnTickListener = listener;
    }

    public void reset() {
        setTextColor(mNormalColor);
        stop();
        setDuration(getDuration());
    }

    public void resetCounterColor() {
        setTextColor(mNormalColor);
    }

    private void onTickEndInternal() {
        setTextColor(mTickEndColor);
    }

    private String setFormatTime(long ms) {
        int elapsedSeconds = (int) (ms / 1000);

        int minutes = 0;
        int seconds = 0;
        int hours = 0;

        if (elapsedSeconds >= 3600) {
            hours = elapsedSeconds / 3600;
            elapsedSeconds -= hours * 3600;
        }
        if (elapsedSeconds >= 60) {
            minutes = elapsedSeconds / 60;
            elapsedSeconds -= minutes * 60;
        }
        seconds = elapsedSeconds;

        return String.format(mFormatString, hours, minutes, seconds);
    }

    //	private Runnable mUpdateRunnable = new Runnable() {
//		
//		@Override
//		public void run() {
//			if(mRunning){
//				/*actually 100ms , give 2ms to execute the following code*/
//				mHandler.postDelayed(mUpdateRunnable, 98);
//				
//				long seconds,end_seconds;
//				if(mStyle == COUNT_DOWN){
//					seconds = mBase - SystemClock.elapsedRealtime();
//				} else {
//					seconds = SystemClock.elapsedRealtime() - mBase;
//				}
//			    end_seconds = mDuration;
//			    if(seconds <= 0 && mStyle == COUNT_DOWN){
//			    	seconds = 0;
//			    	if(mOnTickListener != null){
//			    		mOnTickListener.onEnd();
//			    	}
//			    	stop();
//			    }
//			    if(seconds >= end_seconds && mStyle == COUNT_UP){
//			    	seconds = end_seconds;
//			    	if(mOnTickListener != null){
//			    		mOnTickListener.onEnd();
//			    	}
//			    	stop();
//			    }
//			    String text = setFormatTime(seconds);
//			    setText(text);
//			
//			    if(mOnTickListener != null){
//					mOnTickListener.onTick((int)seconds);
//				}
//		    }else{
//				mHandler.removeCallbacks(mUpdateRunnable);
//			}
//		}
//	};
    private class UpdateTimerTask extends TimerTask {

        @Override
        public void run() {
            post(new Runnable() {

                @Override
                public void run() {
                    if (mRunning) {
                        long milliseconds, end_milliseconds;
                        if (mStyle == COUNT_DOWN) {
                            milliseconds = mBase + (offsetSecond * 1000) - SystemClock.elapsedRealtime();
                        } else {
                            milliseconds = SystemClock.elapsedRealtime() - mBase + (offsetSecond * 1000);
                        }
                        end_milliseconds = mDuration;

                        if (!mIsAlmostEndPosted
                                && milliseconds <= mAlmostEndThreshold && mStyle == COUNT_DOWN) {
                            mIsAlmostEndPosted = true;
                            if (mOnTickListener != null) {
                                mOnTickListener.onAlmostEnd();
                            }
                        }
                        if (!mIsAlmostEndPosted
                                && mStyle == COUNT_UP
                                && (end_milliseconds - milliseconds <= mAlmostEndThreshold)) {
                            mIsAlmostEndPosted = true;
                            if (mOnTickListener != null) {
                                mOnTickListener.onAlmostEnd();
                            }
                        }
                        if (milliseconds <= 0 && mStyle == COUNT_DOWN) {
                            milliseconds = 0;
                            stop();
                            if (mOnTickListener != null) {
                                onTickEndInternal();
                                mOnTickListener.onEnd();
                            }
                        }
                        if (milliseconds >= end_milliseconds && mStyle == COUNT_UP) {
                            milliseconds = end_milliseconds;
                            stop();
                            if (mOnTickListener != null) {
                                onTickEndInternal();
                                mOnTickListener.onEnd();
                            }
                        }
                        String text = setFormatTime(milliseconds);
                        setText(text);

                        if (mOnTickListener != null) {
                            //disable callback in tick per 100 ms
                            mOnTickListener.onTick((int) (milliseconds / 1000));
                        }
                    }
                }
            });

//			if(mRunning){
//				long seconds,end_seconds;
//				if(mStyle == COUNT_DOWN){
//					seconds = mBase - SystemClock.elapsedRealtime();
//				} else {
//					seconds = SystemClock.elapsedRealtime() - mBase;
//				}
//			    end_seconds = mDuration;
//			    if(seconds <= 0 && mStyle == COUNT_DOWN){
//			    	seconds = 0;
//			    	if(mOnTickListener != null){
//			    		post(new Runnable() {
//							
//							@Override
//							public void run() {
//								mOnTickListener.onEnd();		
//							}
//						});
//			    	}
//			    	stop();
//			    }
//			    if(seconds >= end_seconds && mStyle == COUNT_UP){
//			    	seconds = end_seconds;
//			    	if(mOnTickListener != null){
//			    		post(new Runnable() {
//							
//							@Override
//							public void run() {
//								mOnTickListener.onEnd();		
//							}
//						});
//			    	}
//			    	stop();
//			    }
//			    final String text = setFormatTime(seconds);
//			
//			    post(new Runnable() {
//					
//					@Override
//					public void run() {
//						setText(text);	
//					}
//				});
//			
//			    if(mOnTickListener != null){
//			    	final int currentSeconds = (int) seconds;
//			    	post(new Runnable() {
//						
//						@Override
//						public void run() {
//							mOnTickListener.onTick(currentSeconds);		
//						}
//					});
//				}
//		    }
        }
    }

    ;
}
